package com.clementheliou.cheliou.dal.model.photo.util;

import static org.apache.commons.lang3.StringUtils.join;
import static org.apache.commons.lang3.StringUtils.rightPad;
import static org.springframework.util.Assert.isTrue;

import com.clementheliou.cheliou.dal.model.photo.Photo;
import com.clementheliou.cheliou.dal.model.photo.dto.PhotoDTO;
import com.clementheliou.cheliou.dal.model.photo.enumeration.PhotoType;

/**
 * Utilities about the photos objects.
 * 
 * @author Clément HELIOU (clement.heliou@gmail.com)
 * @see {@link Photo};
 * @see {@link PhotoDTO}.
 * @since 1.0
 */
public class PhotoUtils {

	/**
	 * The length that the photo's code is expected to have.
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @since 1.0
	 */
	private static final int EXPECTED_CODE_LENGTH = 14;

	/**
	 * Gets the technical data sheet version of the photo related to the given code.
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @param code the code from which the path will be determinated.
	 * @return the resulting path, ready to be used.
	 * @since 1.0
	 */
	public static String getTechnicalDataSheetPath(final String code) {
		return getPhotoDirectoryPath(code).concat(PhotoType.TECHNICAL_DATA_SHEET.getFileName());
	}

	/**
	 * Gets the large version of the photo related to the given code.
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @param code the code from which the path will be determinated.
	 * @return the resulting path, ready to be used.
	 * @since 1.0
	 */
	public static String getLargePath(final String code) {
		return getPhotoDirectoryPath(code).concat(PhotoType.LARGE.getFileName());
	}

	/**
	 * Gets the medium version of the photo related to the given code.
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @param code the code from which the path will be determinated.
	 * @return the resulting path, ready to be used.
	 * @since 1.0
	 */
	public static String getMediumPath(final String code) {
		return getPhotoDirectoryPath(code).concat(PhotoType.MEDIUM.getFileName());
	}

	/**
	 * Gets the small version of the photo related to the given code.
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @param code the code from which the path will be determinated.
	 * @return the resulting path, ready to be used.
	 * @since 1.0
	 */
	public static String getSmallPath(final String code) {
		return getPhotoDirectoryPath(code).concat(PhotoType.SMALL.getFileName());
	}

	/**
	 * Gets the gallery version of the photo related to the given code.
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @param code the code from which the path will be determinated.
	 * @return the resulting path, ready to be used.
	 * @since 1.0
	 */
	public static String getGalleryPath(final String code) {
		return getPhotoDirectoryPath(code).concat(PhotoType.GALLERY.getFileName());
	}

	/**
	 * Gets the directory path from the given code. This directory contains different versions of
	 * this one (small, medium, large...).
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @param code the code from which the path will be determinated.
	 * @return the directory path with its trailing slash.
	 * @since 1.0
	 */
	private static String getPhotoDirectoryPath(final String code) {

		// 1. Assertions
		isTrue(code.length() == EXPECTED_CODE_LENGTH, "The photo's code should have the expected length at this time.");

		// 2. Process
		final String[] tokens = new String[5];
		tokens[0] = code.substring(0, 4);
		tokens[1] = code.substring(4, 6);
		tokens[2] = code.substring(6, 8);
		tokens[3] = code.substring(8, 9);
		tokens[4] = code.substring(9, 14);

		return rightPad(join(tokens, '/'), EXPECTED_CODE_LENGTH + 5, '/');
	}
}
